package co.gov.medellin.sdep.sisdep.integration.kmrepository;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.sap.security.api.IUser;
import com.sap.security.api.UMFactory;
import com.sapportals.portal.security.usermanagement.UserManagementException;
import com.sapportals.wcm.repository.AccessDeniedException;
import com.sapportals.wcm.repository.Content;
import com.sapportals.wcm.repository.ICollection;
import com.sapportals.wcm.repository.IResource;
import com.sapportals.wcm.repository.NotSupportedException;
import com.sapportals.wcm.repository.ResourceContext;
import com.sapportals.wcm.repository.ResourceException;
import com.sapportals.wcm.repository.ResourceFactory;
import com.sapportals.wcm.util.content.IContent;
import com.sapportals.wcm.util.uri.RID;
import com.sapportals.wcm.util.usermanagement.WPUMFactory;

/**
 * Clase que define los metodos utilitarios para la gestion operativa [crear,
 * actualizar y borrar], de archivos en Sistema KM Repository de archivos en el
 * Portal SAP.
 * 
 * @author carlos.perez@consult-soft.com
 * @version 12/07/2012
 */
public final class KMRepositoryManager {

	/**
	 * 
	 * @param file
	 * @return
	 * @throws IOException
	 */
	public static byte[] getBytesFromFile(File file) throws IOException {
		InputStream is = new FileInputStream(file);

		// Get the size of the file
		long length = file.length();

		if (length > Integer.MAX_VALUE) {
			// File is too large
		}

		// Create the byte array to hold the data
		byte[] bytes = new byte[(int) length];

		// Read in the bytes
		int offset = 0;
		int numRead = 0;
		while (offset < bytes.length
				&& (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) {
			offset += numRead;
		}

		// Ensure all the bytes have been read in
		if (offset < bytes.length) {
			throw new IOException("No se puede leer el archivo " + file.getName());
		}

		// Close the input stream and return bytes
		is.close();
		return bytes;
	}

	/**
	 * 
	 * @param user
	 * @param ruta
	 * @param bytes
	 * @param strFileName
	 * @return
	 */
	public static String uploadFileKM(IUser user, String ruta, byte[] bytes,
			String strFileName) {
		InputStream is = null;
		try {
			is = new ByteArrayInputStream(bytes);
		} catch (Exception e) {
			e.printStackTrace();
			return "El archivo debe representar un flujo o array de Bytes.";
		}

		Content content = new Content(is, "", -1L);

		ResourceContext ctx = null;

		try {
			ctx = new ResourceContext(WPUMFactory.getUserFactory().getEP5User(user));
		} catch (UserManagementException e4) {
			e4.printStackTrace();
			return "Error al crear un contexto de recursos.";

		}

		IResource resource = null;

		try {
			RID rid = RID.getRID(ruta);
			resource = ResourceFactory.getInstance().getResource(rid, ctx);
		} catch (ResourceException e2) {
			e2.printStackTrace();
			return "Error - La ruta '" + ruta + "' no existe.";
		} catch (Exception e2) {
			e2.printStackTrace();
			return "Error - La ruta '" + ruta + "' no existe.";
		}

		ICollection collection = (ICollection) resource;
		// Crear el recurso en KM
		try {
			IResource newResource = collection.createResource(strFileName, null, content);
		} catch (NotSupportedException e3) {
			e3.printStackTrace();
			return "Tipo de archivo no soportado.";
		} catch (AccessDeniedException e3) {
			e3.printStackTrace();
			return "Acceso denegado al crear el recurso en el portal.";
		} catch (ResourceException e3) {
			e3.printStackTrace();
			return "Ya existe un archivo con el nombre: " + strFileName;
		}

		return "true";
	}

	/**
	 * 
	 * @param user
	 * @param ruta
	 * @return
	 */
	public static String deleteFileKM(IUser user, String ruta) {
		ResourceContext ctx = null;

		try {
			ctx = new ResourceContext(WPUMFactory.getUserFactory().getEP5User(user));
		} catch (UserManagementException e4) {
			e4.printStackTrace();
			return "Error al crear un contexto de recursos.";
		}

		IResource resource = null;

		// Eliminar el recurso de KM
		try {
			RID rid = RID.getRID(ruta);

			resource = ResourceFactory.getInstance().getResource(rid, ctx);
			resource.delete();
		} catch (ResourceException e2) {
			e2.printStackTrace();
			return "Error - La ruta '" + ruta + "' no existe.";
		} catch (Exception e2) {
			e2.printStackTrace();
			return "Error al eliminar el archivo.";
		}

		return "true";
	}

	/**
	 * 
	 * @param user
	 * @param ruta
	 * @return
	 */
	public static String getFileContentKM(IUser user, String ruta) {
		ResourceContext ctx = null;

		try {
			ctx = new ResourceContext(WPUMFactory.getUserFactory().getEP5User(user));
		} catch (UserManagementException e4) {
			e4.printStackTrace();
			return "Error al crear un contexto de recursos.";
		}

		IResource resource = null;

		// Eliminar el recurso de KM
		try {
			RID rid = RID.getRID(ruta);

			resource = ResourceFactory.getInstance().getResource(rid, ctx);
			System.err.println("getFileContentKM" + getByteArrayFromResource(resource));

		} catch (ResourceException e2) {
			e2.printStackTrace();
			return "Error - La ruta '" + ruta + "' no existe.";
		} catch (Exception e2) {
			e2.printStackTrace();
			return "Error al eliminar el archivo.";
		}

		return "true";
	}

	/**
	 * 
	 * @param resource
	 * @return
	 * @throws Exception
	 */
	private static byte[] getByteArrayFromResource(IResource resource)
			throws Exception {
		
		IContent content = resource.getContent();
		InputStream in = content.getInputStream();
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		int length;
		byte[] part = new byte[10 * 1024];
		while ((length = in.read(part)) != -1) {
			out.write(part, 0, length);
		}
		in.close();

		return out.toByteArray();
	}
	
	/**
	 * 
	 * @param request
	 * @param response
	 * @return
	 */
	public static IUser getLoggedInUser(HttpServletRequest request, HttpServletResponse response) {
		return UMFactory.getAuthenticator().getLoggedInUser(request, response);
	}
}
